package com.srmt.document.business.quote;

import com.srmt.common.config.ApplicationConfig;
import com.srmt.document.feishu.FeishuDocumentService;
import com.srmt.document.integration.BaseIntegrationTest;
import org.junit.jupiter.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 报价明细表填充示例
 *
 * <p>演示如何使用QuoteTablePopulator自动填充报价明细表
 *
 * <h3>使用场景：</h3>
 * <ol>
 *   <li>多供应商报价对比表</li>
 *   <li>多轮报价跟踪</li>
 *   <li>自动化报价数据录入</li>
 * </ol>
 *
 * @author SRMT Development Team
 * @since 1.0.0
 */
@Tag("integration")
@Tag("business")
@Tag("quote")
@DisplayName("报价明细表填充示例")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class QuoteTablePopulateExample extends BaseIntegrationTest {

    private static final Logger logger = LoggerFactory.getLogger(QuoteTablePopulateExample.class);

    private QuoteTablePopulator quotePopulator;

    /**
     * 设置测试环境
     */
    @BeforeEach
    public void setupQuotePopulator() {
        quotePopulator = new QuoteTablePopulator(contentReader, contentWriter);
    }

    /**
     * 示例1：基础使用 - 填充单个供应商的单轮报价
     */
    @Test
    @Order(1)
    @DisplayName("示例1：基础使用 - 单供应商单轮报价")
    public void example01_BasicUsage() throws Exception {
        logger.info("========== 示例1：基础使用 - 单供应商单轮报价 ==========");

        // 创建测试文档
        String docId = createTestDocument("报价明细表_示例1");

        // 初始化表格结构（模拟已有的报价明细表）
        createInitialQuoteTable(docId);

        // 准备第一轮报价数据
        SupplierQuoteData quote = SupplierQuoteData.builder()
                .supplierName("A-供应商")
                .round(1)
                .addQuoteValues(
                        "100.00",  // 出厂价①
                        "95.00",   // 包装②
                        "90.00",   // 物流③
                        "85.00",   // 分摊④
                        "80.00",   // 产品单价
                        "75.00",   // 单价价格(不含分摊)
                        "70.00",   // 单合价格 (元/台)
                        "65.00"    // 单后备器件单价
                )
                .build();

        // 填充数据
        List<SupplierQuoteData> quotes = Arrays.asList(quote);
        quotePopulator.populateQuoteTable(docId, "报价明细表", quotes);

        logger.info("示例1执行成功，文档ID: {}", docId);
    }

    /**
     * 示例2：多供应商对比 - 同时填充多个供应商的报价
     */
    @Test
    @Order(2)
    @DisplayName("示例2：多供应商对比")
    public void example02_MultipleSuppliers() throws Exception {
        logger.info("========== 示例2：多供应商对比 ==========");

        String docId = createTestDocument("报价明细表_示例2");
        createInitialQuoteTable(docId);

        // 准备多个供应商的第一轮报价
        List<SupplierQuoteData> quotes = Arrays.asList(
                // A供应商第一轮报价
                SupplierQuoteData.builder()
                        .supplierName("A-供应商")
                        .round(1)
                        .addQuoteValues("100", "95", "90", "85", "80", "75", "70", "65")
                        .build(),

                // B供应商第一轮报价
                SupplierQuoteData.builder()
                        .supplierName("B-供应商")
                        .round(1)
                        .addQuoteValues("105", "98", "92", "87", "82", "77", "72", "67")
                        .build(),

                // C供应商第一轮报价
                SupplierQuoteData.builder()
                        .supplierName("C-供应商")
                        .round(1)
                        .addQuoteValues("98", "93", "88", "83", "78", "73", "68", "63")
                        .build()
        );

        // 批量填充
        quotePopulator.populateQuoteTable(docId, "报价明细表", quotes);

        logger.info("示例2执行成功，已填充3个供应商的第一轮报价，文档ID: {}", docId);
    }

    /**
     * 示例3：多轮报价 - 填充多轮次的报价数据
     */
    @Test
    @Order(3)
    @DisplayName("示例3：多轮报价跟踪")
    public void example03_MultipleRounds() throws Exception {
        logger.info("========== 示例3：多轮报价跟踪 ==========");

        String docId = createTestDocument("报价明细表_示例3");
        createInitialQuoteTable(docId);

        // 第一轮报价
        List<SupplierQuoteData> round1Quotes = Arrays.asList(
                SupplierQuoteData.builder()
                        .supplierName("A-供应商")
                        .round(1)
                        .addQuoteValues("100", "95", "90", "85", "80", "75", "70", "65")
                        .build(),
                SupplierQuoteData.builder()
                        .supplierName("B-供应商")
                        .round(1)
                        .addQuoteValues("105", "98", "92", "87", "82", "77", "72", "67")
                        .build()
        );

        quotePopulator.populateQuoteTable(docId, "报价明细表", round1Quotes);
        logger.info("第一轮报价填充完成");

        // 第二轮报价（价格下调）
        List<SupplierQuoteData> round2Quotes = Arrays.asList(
                SupplierQuoteData.builder()
                        .supplierName("A-供应商")
                        .round(2)
                        .addQuoteValues("98", "93", "88", "83", "78", "73", "68", "63")
                        .build(),
                SupplierQuoteData.builder()
                        .supplierName("B-供应商")
                        .round(2)
                        .addQuoteValues("102", "95", "90", "85", "80", "75", "70", "65")
                        .build()
        );

        quotePopulator.populateQuoteTable(docId, "报价明细表", round2Quotes);
        logger.info("第二轮报价填充完成");

        // 第三轮报价
        List<SupplierQuoteData> round3Quotes = Arrays.asList(
                SupplierQuoteData.builder()
                        .supplierName("A-供应商")
                        .round(3)
                        .addQuoteValues("96", "91", "86", "81", "76", "71", "66", "61")
                        .build(),
                SupplierQuoteData.builder()
                        .supplierName("B-供应商")
                        .round(3)
                        .addQuoteValues("100", "93", "88", "83", "78", "73", "68", "63")
                        .build()
        );

        quotePopulator.populateQuoteTable(docId, "报价明细表", round3Quotes);
        logger.info("第三轮报价填充完成");

        logger.info("示例3执行成功，已完成3轮报价填充，文档ID: {}", docId);
    }

    /**
     * 示例4：增量更新 - 新供应商加入竞标
     */
    @Test
    @Order(4)
    @DisplayName("示例4：增量更新 - 新供应商加入")
    public void example04_IncrementalUpdate() throws Exception {
        logger.info("========== 示例4：增量更新 - 新供应商加入竞标 ==========");

        String docId = createTestDocument("报价明细表_示例4");
        createInitialQuoteTable(docId);

        // 初始状态：A、B两家供应商已完成2轮报价
        List<SupplierQuoteData> initialQuotes = Arrays.asList(
                SupplierQuoteData.builder().supplierName("A-供应商").round(1)
                        .addQuoteValues("100", "95", "90", "85", "80", "75", "70", "65").build(),
                SupplierQuoteData.builder().supplierName("A-供应商").round(2)
                        .addQuoteValues("98", "93", "88", "83", "78", "73", "68", "63").build(),
                SupplierQuoteData.builder().supplierName("B-供应商").round(1)
                        .addQuoteValues("105", "98", "92", "87", "82", "77", "72", "67").build(),
                SupplierQuoteData.builder().supplierName("B-供应商").round(2)
                        .addQuoteValues("102", "95", "90", "85", "80", "75", "70", "65").build()
        );

        quotePopulator.populateQuoteTable(docId, "报价明细表", initialQuotes);
        logger.info("初始状态：A、B供应商已完成2轮报价");

        // 新增C供应商加入竞标（直接参与第3轮）
        List<SupplierQuoteData> newSupplierQuotes = Arrays.asList(
                // C供应商第3轮报价
                SupplierQuoteData.builder()
                        .supplierName("C-供应商")
                        .round(3)
                        .addQuoteValues("95", "90", "85", "80", "75", "70", "65", "60")
                        .build(),

                // A、B供应商也提交第3轮报价
                SupplierQuoteData.builder().supplierName("A-供应商").round(3)
                        .addQuoteValues("96", "91", "86", "81", "76", "71", "66", "61").build(),
                SupplierQuoteData.builder().supplierName("B-供应商").round(3)
                        .addQuoteValues("100", "93", "88", "83", "78", "73", "68", "63").build()
        );

        quotePopulator.populateQuoteTable(docId, "报价明细表", newSupplierQuotes);
        logger.info("增量更新：C供应商加入，所有供应商完成第3轮报价");

        logger.info("示例4执行成功，文档ID: {}", docId);
    }

    /**
     * 示例5：完整业务流程 - 模拟真实采购流程
     */
    @Test
    @Order(5)
    @DisplayName("示例5：完整业务流程模拟")
    public void example05_CompleteBusinessFlow() throws Exception {
        logger.info("========== 示例5：完整业务流程模拟 ==========");

        String docId = createTestDocument("报价明细表_完整流程");
        createInitialQuoteTable(docId);

        // 阶段1：首轮报价（3家供应商）
        logger.info("阶段1：收集首轮报价");
        List<SupplierQuoteData> phase1 = createMockQuotes(
                Arrays.asList("A-供应商", "B-供应商", "C-供应商"),
                1,
                new double[]{100, 105, 98}
        );
        quotePopulator.populateQuoteTable(docId, "报价明细表", phase1);

        // 阶段2：议价后第二轮报价（价格下调5%）
        logger.info("阶段2：议价后提交第二轮报价");
        List<SupplierQuoteData> phase2 = createMockQuotes(
                Arrays.asList("A-供应商", "B-供应商", "C-供应商"),
                2,
                new double[]{95, 100, 93}
        );
        quotePopulator.populateQuoteTable(docId, "报价明细表", phase2);

        // 阶段3：C供应商出局，A、B进入第三轮
        logger.info("阶段3：筛选后进入第三轮");
        List<SupplierQuoteData> phase3 = createMockQuotes(
                Arrays.asList("A-供应商", "B-供应商"),
                3,
                new double[]{92, 97}
        );
        quotePopulator.populateQuoteTable(docId, "报价明细表", phase3);

        // 阶段4：新供应商D加入竞标
        logger.info("阶段4：新供应商D提交报价，A、B继续优化");
        List<SupplierQuoteData> phase4 = Arrays.asList(
                createMockQuote("D-供应商", 4, 90),
                createMockQuote("A-供应商", 4, 89),
                createMockQuote("B-供应商", 4, 94)
        );
        quotePopulator.populateQuoteTable(docId, "报价明细表", phase4);

        logger.info("示例5执行成功，完整业务流程模拟完毕，文档ID: {}", docId);
    }

    // ============ 辅助方法 ============

    /**
     * 创建初始报价明细表结构
     */
    private void createInitialQuoteTable(String docId) throws Exception {
        // 添加标题
        contentWriter.appendTextAfter(docId, "", "# 报价明细表");
        contentWriter.appendTextAfter(docId, "# 报价明细表", "\n\n**项目名称**：XX产品采购\n**截止日期**：2024-12-31\n");

        // 创建基础表格结构（仅包含固定列）
        List<List<String>> initialTable = Arrays.asList(
                Arrays.asList("报价期细", "目标价"),
                Arrays.asList("", ""),
                Arrays.asList("出厂价①", ""),
                Arrays.asList("包装②", ""),
                Arrays.asList("物流③", ""),
                Arrays.asList("分摊④", ""),
                Arrays.asList("产品单价\n(①+②+③+④)", ""),
                Arrays.asList("单价价格(不含分摊)", ""),
                Arrays.asList("单合价格 (元/台) (含分摊、物流、物流)", ""),
                Arrays.asList("单后备器件单价\n(除分摊外部分一次性费用)", "")
        );

        contentWriter.createTable(docId, "# 报价明细表", 10, 2, initialTable);

        logger.info("初始报价明细表创建完成");
    }

    /**
     * 批量创建模拟报价数据
     */
    private List<SupplierQuoteData> createMockQuotes(List<String> suppliers, int round, double[] basePrices) {
        List<SupplierQuoteData> quotes = new ArrayList<>();
        for (int i = 0; i < suppliers.size(); i++) {
            quotes.add(createMockQuote(suppliers.get(i), round, basePrices[i]));
        }
        return quotes;
    }

    /**
     * 创建单个模拟报价数据
     */
    private SupplierQuoteData createMockQuote(String supplierName, int round, double basePrice) {
        return SupplierQuoteData.builder()
                .supplierName(supplierName)
                .round(round)
                .addQuoteValues(
                        String.format("%.2f", basePrice),
                        String.format("%.2f", basePrice * 0.95),
                        String.format("%.2f", basePrice * 0.90),
                        String.format("%.2f", basePrice * 0.85),
                        String.format("%.2f", basePrice * 0.80),
                        String.format("%.2f", basePrice * 0.75),
                        String.format("%.2f", basePrice * 0.70),
                        String.format("%.2f", basePrice * 0.65)
                )
                .build();
    }
}
